<template>



  <div class="config-panel" @drop="onDrop" :style="{ maxWidth: value.width }">
    <h3 v-if="value.title" v-text="value.title" style="padding-bottom: 20px;"></h3>
    <el-empty v-if="value.emptyText && !value.formItems?.length" :description="value.emptyText"></el-empty>
    <el-form @submit.native.prevent="" v-else :rules="value.rules" :model="value.formDataWithDataKey" ref="form"
      :label-suffix="value.labelSuffix" :size="value.size" :label-width="value.labelWidth || 'auto'"
      :label-position="value.labelPosition">
      <draggable :disabled="!value.draggable" :sort="value.sortable" v-model="value.formItems" chosen-class="chosen"
        animation="200" @add="onAdd" group="components" class="config-panel-grid drop-area"
        :style="config_panel_grid_style">
        <div v-for="(item) in value.formItems" @click="handleSelectItem(item)" class="config-panel-item"
          :class="{ setected: value.selectable && value.selectedItem?.key == item.key, readonly: value.readonly || item.readonly }"
          :style="setGridSpan(item)" :title="item.helpText">
          <div class="action-bar"><span @click.stop.prevent="removeItem(item)">x</span></div>
          <el-form-item :key="item.key" :label="item.label" :required="item.required" :prop="item.dataKey"
            :[dynamicrulesprop]="item.rules" :data-hasBorder="item.hasBorder">
            <component v-if="item.key.startsWith('attrs.')" v-model="value.formData.attrs[resolveKey(item.key)]"
              :is="getComp(item)" v-bind="item.attrs">
            </component>
            <component v-else v-model="value.formData[item.key]" :is="getComp(item)" v-bind="item.attrs">
            </component>
          </el-form-item>
        </div>

      </draggable>
    </el-form>


  </div>



</template>

<script>
export default {

  computed: {
    dynamicrulesprop() {
      return Object.keys(this.value.rules ?? {}).length ? '_never_rules' : 'rules'
    },
    config_panel_grid_style() {
      return {
        gridTemplateColumns: `repeat(${this.value.cols ?? 1}, 1fr)`,
        rowGap: this.value.rowGap ?? 'initial',
        columnGap: this.value.columnGap ?? 'initial'
      }
    }
  },
  mounted() {
    // console.log('this',this) 
  },
  props: {
    value: {
      required: true,
      type: Object,
      default() {
        return {}
      }
    }
  },
  data() {
    return {
      comps: {},  //通过generateComponent 生成的组件
      selectedItem: null

    }
  },
  model: {
    event: 'change'
  },
  methods: {
    resolveKey(key) {
      return key.split('.')[1]
    },
    removeItem(item) {
      this.value.formItems = this.value.formItems.filter(i => i.key !== item.key)
      this.handleSelectItem(null)
    },
    setGridSpan(item) {
      return {
        gridColumn: `span ${item.span ?? 1}`
      }
    },
    handleSelectItem(item) {
      if (!this.value.selectable || item == this.value.selectedItem) return
      this.value.selectedItem = item
    },
    onDrop(e) {

    },
    onAdd(e) {
    },
    getComp(item) {
      if (item.compName) return item.compName
      else if (item.templateStr) {
        try {
          return this.generateComponent(item)
        } catch (error) {
          console.error('getComp 出错',error)
        }
      }
    },
    generateComponent(item) {
      const { key,templateStr } = item

      try {
        return this.comps[key] ??= Vue.extend({
          created() {
            // console.log('generateComponent',this)
          },
          props: ['value'],
          model: {
            event: 'change'
          },
          computed: {
            _value: {
              get() { return this.value },
              set(val) {
                this.$emit('change',val)
              }
            }
          },
          template: templateStr
        })

      } catch (error) {
        console.error('generateComponent 出错',error)
      }
    }
  }
}
</script>
<style lang="less" scoped>
.config-panel {
  background-color: #fff;
  padding: var(--layout-padding, 10px);


  .readonly * {
    pointer-events: none;
  }


  .action-bar {
    pointer-events: all;
    display: none;
    column-gap: 10px;
    position: absolute;
    top: 0;
    right: 5px;
    transform: translateY(-60%);
    z-index: 1;

    >* {
      background: #fff;
      width: 18px;
      height: 18px;
      border-radius: 50%;
      border: 1px solid #ff5555;
      color: #ff5555;
      overflow: hidden;
      text-align: center;
      line-height: 18px;
      cursor: pointer;
    }
  }

  .config-panel-item {
    border: 1px dashed transparent;
  }

  ::v-deep(.el-form-item[data-hasBorder])> {

    .el-form-item__label-wrap,
    .el-form-item__content {
      border-width: 1px;
      border-color: #000;
      border-style: solid;
    }
  }

  .setected {
    border-color: #1890ff;
    position: relative;
    border-style: dashed;

    .action-bar {
      display: flex;

    }
  }

  ::v-deep(.config-panel-grid) {
    display: grid;
    align-items: start;
  }

  ::v-deep(.drop-area) {
    // border: 1px dashed #ccc;
    min-height: 80px;
  }
}
</style>
